package com.platform.modules.sms;

import cn.hutool.core.util.PhoneUtil;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.CharUtil;
import com.platform.common.utils.Constant;
import com.platform.common.utils.JedisUtil;
import com.platform.common.utils.StringUtils;
import com.platform.modules.sms.entitys.SmsTemplateEntity;
import com.platform.modules.sms.util.SmsUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 短信发送
 *
 * @author hch
 */
@Slf4j
public class SmsSend {

    private ISmsSend smsSend;

    private JedisUtil jedisUtil;

    // 下方参数需要进行封装
    public String phone;
    public String userId;
    public Object params;
    public String content;
    public String code;

    // 发送成功的回调
    public Consumer<SmsSend> sendComplete = null;

    // 有效期为5分钟
    public static final int VALID = 300;
    // 1分钟后可重发
    public static final int STINT = 60;

    /**
     * 构建短信发送辅助类
     *
     * @param smsSend   ISmsSend 实现类
     * @param phone     手机号码
     * @param jedisUtil redis缓存
     * @param userId    发送的用户ID
     * @param params    额外参数（可以为空）
     */
    public SmsSend(ISmsSend smsSend, String phone, JedisUtil jedisUtil, String userId, Object params) {
        // 校验手机号码不能为空
        if (!PhoneUtil.isMobile(phone)) {
            throw new BusinessException("手机号码有误！");
        }
        this.smsSend = smsSend;
        this.phone = phone;
        this.jedisUtil = jedisUtil;
        this.userId = StringUtils.isBlank(userId) ? "0" : userId;
        this.params = params;
    }

    /**
     * 校验图像验证码
     *
     * @param uuid
     * @param captcha
     * @return
     */
    public SmsSend captchaValidate(String uuid, String captcha) {
        com.platform.modules.sms.util.SmsUtil.captchaValidate(jedisUtil, uuid, captcha);
        return this;
    }

    /**
     * 发送验证码(存数据库和redis)
     *
     * @param function 短信内容构建回调
     */
    public void sendCode(Function<String, String> function) {
        this.content = function.apply(this.code);
        send();
    }

    /**
     * 生成code
     *
     * @return this
     */
    public SmsSend createCode(int lenght) {
        String smsCode;
        String cacheKey = Constant.PRE_SMS + phone;
        // 一分钟之内不能重复发送短信
        if (jedisUtil.ttl(cacheKey) > VALID - STINT) {
            throw new BusinessException("短信已发送");
        } else {
            String code = jedisUtil.get(cacheKey);
            if (StringUtils.isNotBlank(code)) {
                smsCode = code;
            } else {
                // 生成验证码
                smsCode = CharUtil.getRandomNum(lenght);
            }
        }
        this.code = smsCode;

        sendComplete = (x) -> {
            // 将验证码存入redis
            jedisUtil.set(cacheKey, smsCode, SmsSend.VALID);
            // 设置校验错误次数
            jedisUtil.set(Constant.PRE_SMS_ERROR_COUNT + phone, "0", SmsSend.VALID);
        };

        return this;
    }

    private void send() {
        if (StringUtils.isEmpty(content)) {
            throw new BusinessException("短信内容不能为空！");
        }
        // 短信发送
        smsSend.sendSms(this);
        // 成功后的回调 目前主要用于设置验证码缓存
        if (sendComplete != null) {
            sendComplete.accept(this);
        }
    }

    public void autoSend(String configId) {
        autoSend(configId, null);
    }

    /**
     * 自动构建短信发送模板
     *
     * @param configId
     * @param params
     */
    public void autoSend(String configId, Map<String, String> params) {
        if(StringUtils.isBlank(configId)){
            throw new BusinessException("模板ID不能为空！");
        }
        // 获取配置
        SmsTemplateEntity entity = smsSend.getTemplate(configId);
        // 设置短信内容
        SmsUtil.autoBuild(entity, this, params);
        // 发送
        send();
    }

}
